package top.jolyoulu.modules.poimodule.excel.reader;

import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import top.jolyoulu.modules.poimodule.excel.annotation.ExcelImport;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Author: JolyouLu
 * @Date: 2023/12/17 16:54
 * @Description
 */
@Setter
public abstract class AbsExcelReaderHandler<T> implements ExcelReaderHandler {

    protected static final int DEFAULT_SHEET_INDEX = 0;
    /**
     * 当前读取的sheet地址
     */
    protected Integer sheetIndex = DEFAULT_SHEET_INDEX;
    /**
     * 需要处理的数据类型
     */
    protected Class<T> dataType;
    /**
     * 数据类型中的字段
     */
    protected Map<Integer, Field> fieldMap;
    /**
     * 开始读取的行号
     */
    protected Integer startRow;
    /**
     * 返回结果
     */
    protected List<T> result = new ArrayList<>();
    /**
     * 记录的row
     */
    private Integer recordRow = -1;
    /**
     * 记录的Data
     */
    private T recordData = null;

    /**
     * 需要接受一个Class对象，用于加载对象中的注解
     *
     * @param dataType
     */
    public AbsExcelReaderHandler(Class<T> dataType) {
        this.dataType = dataType;
        this.fieldMap = getFieldMapOfExcelImport(dataType);
    }

    @Override
    public void handler(Integer row, Integer column, String value) {
        //startRow之前的数据不处理
        if (row < startRow) {
            return;
        }
        //与记录值不同，表示是一个新的行，创建新对象
        if (!recordRow.equals(row)) {
            recordRow = row;
            recordData = handlerRow(row, column, value);
            result.add(recordData);
        }
        if (Objects.nonNull(recordData) && StringUtils.isNoneBlank(value)) {
            handlerColumn(recordData,row,column,value);
        }
    }

    /**
     * 当进入一个新的行后触发该方法
     * 通常在这里构建一个item中的对象
     * @param row 当前行
     * @param column 当前列
     * @param value 值
     * @return
     */
    protected abstract T handlerRow(Integer row, Integer column, String value);

    /**
     * 当进入一个新的列后触发该方法
     * 通常在这里判断与为每个item添加值
     * @param row 当前行
     * @param column 当前列
     * @param value 值
     * @return
     */
    protected abstract void handlerColumn(T recordData, Integer row, Integer column, String value);

    /**
     * 获取类中包含的ExcelImport信息
     *
     * @param dataType
     * @return
     */
    protected Map<Integer, Field> getFieldMapOfExcelImport(Class<T> dataType) {
        //获取类中的所有属性
        Field[] fields = dataType.getDeclaredFields();
        if (Objects.isNull(fields) || fields.length <= 0) {
            return Collections.emptyMap();
        }
        HashMap<Integer, Field> res = new HashMap<>();
        for (Field field : fields) {
            ExcelImport annotation = field.getAnnotation(ExcelImport.class);
            if (Objects.isNull(annotation)) {
                continue;
            }
            int titleIndex = annotation.titleIndex();
            if (res.containsKey(titleIndex)) {
                throw new RuntimeException("ExcelImport => titleIndex 不能重复");
            }
            if (titleIndex <= 0) {
                throw new RuntimeException("ExcelImport => titleIndex 必须>0");
            }
            field.setAccessible(true);
            res.put(annotation.titleIndex(), field);
        }
        return res;
    }

    /**
     * 获取结果集
     * @return
     */
    public List<T> getData() {
        return result;
    }
}
